//原文链接：https://blog.csdn.net/ITSOK_123/article/details/124383184
//栈实现队列
class MyQueue {
public:
    //使用两个栈来模拟队列的操作
    //in和out分别用来模拟入栈和出栈
    stack<int> stIn;
    stack<int> stOut;
    MyQueue() {   
    }
    void push(int x) {
    	//push不用处理stOut栈
    	//这样使得在插入到队列时只用操作一个栈
        stIn.push(x);
    }
    int pop() {
        //只有专门用来弹出的栈为空才会再次压入
        //如果弹出栈为空，就将元素全部转移到这个栈
        if(stOut.empty()){
            while(!stIn.empty()){
                stOut.push(stIn.top());
                stIn.pop();
            }
        }
        int res = stOut.top();
        stOut.pop();
        return res;
    }
    
    int peek() {
        int res = this->pop();
        //不应该弹出，所以要添加回去，弹出再添加，元素的位置不会改变
        stOut.push(res);
        return res;
    }
    
    bool empty() {
        return stIn.empty() && stOut.empty();
    }
};

/**
 * Your MyQueue object will be instantiated and called as such:
 * MyQueue* obj = new MyQueue();
 * obj->push(x);
 * int param_2 = obj->pop();
 * int param_3 = obj->peek();
 * bool param_4 = obj->empty();
 */

//队列实现栈
class MyStack {
public:
    queue<int> queIN;
    MyStack() {

    }
    
    void push(int x) {
        queIN.push(x);
    }
    
    int pop() {
    	//要输出最后一个元素
    	//逐个处理最后一个元素前面的所有元素
        int size = queIN.size()-1;
        int temp;
        while(size--){
        	//前面的元素按照顺序放到尾元素后面
            temp = queIN.front();
            queIN.push(temp);
            queIN.pop();    
        }
        int res = queIN.front();
        queIN.pop();
        return res;
    }
    
    int top() {
        return queIN.back();
    }
    
    bool empty() {
        return queIN.empty();
    }
};

/**
 * Your MyStack object will be instantiated and called as such:
 * MyStack* obj = new MyStack();
 * obj->push(x);
 * int param_2 = obj->pop();
 * int param_3 = obj->top();
 * bool param_4 = obj->empty();
 */

